package com.sc.nft.service.impl;

import cn.hutool.core.date.DateTime;
import cn.hutool.core.date.DateUtil;
import com.meta.component.base.api.CommonResult;
import com.meta.component.base.api.ResultCode;
import com.meta.push.plat.client.api.MetaPushPlatClient;
import com.meta.push.plat.client.req.PushUserBindTagsRequest;
import com.sc.nft.dao.PushCidRelationTagDao;
import com.sc.nft.dao.UserPushConfDao;
import com.sc.nft.dao.UserRelationPushCidDao;
import com.sc.nft.entity.PushCidRelationTag;
import com.sc.nft.entity.UserInfo;
import com.sc.nft.entity.UserPushConf;
import com.sc.nft.entity.UserRelationPushCid;
import com.sc.nft.entity.vo.UserPushConfVo;
import com.sc.nft.enums.PushNoticeEnableEnum;
import com.sc.nft.enums.PushSourceEnum;
import com.sc.nft.exception.GlobalRunTimeException;
import com.sc.nft.service.UserPushConfService;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.Collections;
import java.util.Objects;

/**
 * @author 刘国航
 * @desc
 * @since 2024/6/14 11:08
 */
@Slf4j
@RequiredArgsConstructor
@Service
public class UserPushConfServiceImpl implements UserPushConfService {

    private final UserPushConfDao userPushConfDao;
    private final MetaPushPlatClient metaPushPlatClient;
    private final UserRelationPushCidDao userRelationPushCidDao;
    private final PushCidRelationTagDao pushCidRelationTagDao;

    @Override
    public UserPushConfVo detailConf(UserInfo userInfo) {
        UserPushConf userPushConf = userPushConfDao.getByUserId(userInfo.getId());
        UserPushConfVo userPushConfVo = new UserPushConfVo();
        if (Objects.nonNull(userPushConf)) {
            userPushConfVo.setEnableMallOrderPush(userPushConf.getEnableMallOrderPush());
            userPushConfVo.setEnablePledgeTaskPush(userPushConf.getEnablePledgeTaskPush());
            userPushConfVo.setEnableNoticePush(userPushConf.getEnableNoticePush());
        } else {
            userPushConfVo.setEnableMallOrderPush(true);
            userPushConfVo.setEnablePledgeTaskPush(true);
            userPushConfVo.setEnableNoticePush(true);
        }
        return userPushConfVo;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void updateConf(Boolean enableMallOrderPush, Boolean enablePledgeTaskPush, Boolean enableNoticePush, UserInfo userInfo) {
        UserPushConf userPushConf = userPushConfDao.getByUserId(userInfo.getId());
        if (Objects.nonNull(userPushConf)) {
            Boolean oldEnableNoticePush = userPushConf.getEnableNoticePush();
            userPushConf.setEnableMallOrderPush(enableMallOrderPush);
            userPushConf.setEnablePledgeTaskPush(enablePledgeTaskPush);
            userPushConf.setEnableNoticePush(enableNoticePush);
            userPushConf.updateById();
            if (!Objects.equals(enableNoticePush, oldEnableNoticePush)) {
                pushUserBindTag(userInfo.getId(), enableNoticePush, true);
            }
        } else {
            userPushConf = new UserPushConf();
            userPushConf.setUserId(userInfo.getId());
            userPushConf.setEnableMallOrderPush(enableMallOrderPush);
            userPushConf.setEnablePledgeTaskPush(enablePledgeTaskPush);
            userPushConf.setEnableNoticePush(enableNoticePush);
            userPushConf.insert();
            pushUserBindTag(userInfo.getId(), enableNoticePush, true);
        }
    }

    @Override
    public void pushUserBindTag(Long userId, Boolean enableNoticePush, Boolean exception) {
        UserRelationPushCid userRelationPushCid = userRelationPushCidDao.getByUserId(userId);
        if (Objects.isNull(userRelationPushCid)) {
            return;
        }
        DateTime now = DateTime.now();
        PushCidRelationTag pushCidRelationTag = pushCidRelationTagDao.getByCid(userRelationPushCid.getCid());
        boolean sameDay = false;
        if (Objects.nonNull(pushCidRelationTag)) {
            sameDay = DateUtil.isSameDay(pushCidRelationTag.getBindDate(), now);
            if (sameDay && pushCidRelationTag.getBindCount() >= 10) {
                if (exception) {
                    throw new GlobalRunTimeException("已超过当日最大调整次数");
                } else {
                    return;
                }
            }
        }
        PushUserBindTagsRequest pushUserBindTagsRequest = new PushUserBindTagsRequest();
        pushUserBindTagsRequest.setSource(PushSourceEnum.METAGO.getCode());
        pushUserBindTagsRequest.setCid(userRelationPushCid.getCid());
        pushUserBindTagsRequest.setTags(Collections.singletonList(enableNoticePush ? PushNoticeEnableEnum.ENABLE_NOTICE.getKey() : PushNoticeEnableEnum.DISABLE_NOTICE.getKey()));
        CommonResult<Boolean> commonResult = metaPushPlatClient.userBindTags(pushUserBindTagsRequest);
        if (Objects.equals(commonResult.getCode(), ResultCode.SUCCESS.getCode())) {
            if (Objects.nonNull(pushCidRelationTag)) {
                pushCidRelationTag.setBindDate(now);
                pushCidRelationTag.setBindCount((sameDay ? pushCidRelationTag.getBindCount() : 0) + 1);
                pushCidRelationTag.setTag(enableNoticePush ? PushNoticeEnableEnum.ENABLE_NOTICE.getKey() : PushNoticeEnableEnum.DISABLE_NOTICE.getKey());
                pushCidRelationTag.updateById();
            } else {
                pushCidRelationTag = new PushCidRelationTag();
                pushCidRelationTag.setCid(userRelationPushCid.getCid());
                pushCidRelationTag.setBindDate(now);
                pushCidRelationTag.setBindCount(1);
                pushCidRelationTag.setTag(enableNoticePush ? PushNoticeEnableEnum.ENABLE_NOTICE.getKey() : PushNoticeEnableEnum.DISABLE_NOTICE.getKey());
                pushCidRelationTag.setVersion(0);
                pushCidRelationTag.insert();
            }
        } else {
            log.error(commonResult.getMessage());
            if (exception) {
                throw new GlobalRunTimeException(commonResult.getMessage());
            }
        }
    }

}
